home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / WPrefs.app / WPrefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-29  |  25.1 KB  |  1,073 lines

  1. /* WPrefs.c- main window and other basic stuff
  2.  * 
  3.  *  WPrefs - Window Maker Preferences Program
  4.  * 
  5.  *  Copyright (c) 1998 Alfredo K. Kojima
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23.  
  24. #include "WPrefs.h"
  25. #include <assert.h>
  26.  
  27.  
  28. extern Panel *InitWindowHandling(WMScreen *scr, WMWindow *win);
  29.  
  30. extern Panel *InitKeyboardSettings(WMScreen *scr, WMWindow *win);
  31.  
  32. extern Panel *InitMouseSettings(WMScreen *scr, WMWindow *win);
  33.  
  34. extern Panel *InitKeyboardShortcuts(WMScreen *scr, WMWindow *win);
  35.  
  36. extern Panel *InitWorkspace(WMScreen *scr, WMWindow *win);
  37.  
  38. extern Panel *InitFocus(WMScreen *scr, WMWindow *win);
  39.  
  40. extern Panel *InitPreferences(WMScreen *scr, WMWindow *win);
  41.  
  42. extern Panel *InitFont(WMScreen *scr, WMWindow *win);
  43.  
  44. extern Panel *InitConfigurations(WMScreen *scr, WMWindow *win);
  45.  
  46. extern Panel *InitPaths(WMScreen *scr, WMWindow *win);
  47.  
  48. extern Panel *InitMenu(WMScreen *scr, WMWindow *win);
  49.  
  50. extern Panel *InitExpert(WMScreen *scr, WMWindow *win);
  51.  
  52. extern Panel *InitMenuPreferences(WMScreen *scr, WMWindow *win);
  53.  
  54. extern Panel *InitIcons(WMScreen *scr, WMWindow *win);
  55.  
  56. extern Panel *InitThemes(WMScreen *scr, WMWindow *win);
  57.  
  58. extern Panel *InitAppearance(WMScreen *scr, WMWindow *win);
  59.  
  60.  
  61.  
  62.  
  63. #define ICON_TITLE_FONT "-adobe-helvetica-bold-r-*-*-10-*"
  64. #define ICON_TITLE_VFONT "-adobe-helvetica-bold-r-*-*-10-[]-*"
  65.  
  66.  
  67. #define MAX_SECTIONS 16
  68.  
  69.  
  70. typedef struct _WPrefs {    
  71.     WMWindow *win;
  72.  
  73.     WMScrollView *scrollV;
  74.     WMFrame *buttonF;
  75.     WMButton *sectionB[MAX_SECTIONS];
  76.     
  77.     int sectionCount;
  78.  
  79.     WMButton *saveBtn;
  80.     WMButton *closeBtn;
  81.     WMButton *undoBtn;
  82.     WMButton *undosBtn;
  83.  
  84.     WMButton *balloonBtn;
  85.  
  86.     WMFrame *banner;
  87.     WMLabel *nameL;
  88.     WMLabel *versionL;
  89.     WMLabel *creditsL;
  90.     WMLabel *statusL;
  91.     
  92.     Panel *currentPanel;
  93. } _WPrefs;
  94.  
  95.  
  96. static _WPrefs WPrefs;
  97.  
  98. /* system wide defaults dictionary. Read-only */
  99. static proplist_t GlobalDB = NULL;
  100. /* user defaults dictionary */
  101. static proplist_t WindowMakerDB = NULL;
  102.  
  103.  
  104. static Bool TIFFOK = False;
  105.  
  106.  
  107. #define INITIALIZED_PANEL    (1<<0)
  108.  
  109.  
  110.  
  111.  
  112. static void loadConfigurations(WMScreen *scr, WMWindow *mainw);
  113.  
  114. static void savePanelData(Panel *panel);
  115.  
  116. static void prepareForClose();
  117.  
  118. void
  119. quit(WMWidget *w, void *data)
  120. {
  121.     prepareForClose();
  122.  
  123.     exit(0);
  124. }
  125.  
  126.  
  127. static void
  128. save(WMWidget *w, void *data)
  129. {
  130.     int i;
  131.     proplist_t p1, p2;
  132.     proplist_t keyList;
  133.     proplist_t key;
  134.     char *msg = "Reconfigure";
  135.     XEvent ev;
  136.  
  137.  
  138. /*    puts("gathering data");*/
  139.     for (i=0; i<WPrefs.sectionCount; i++) {
  140.     PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
  141.     if ((rec->callbacks.flags & INITIALIZED_PANEL))
  142.         savePanelData((Panel*)rec);
  143.     }
  144. /*    puts("compressing data");*/
  145.     /* compare the user dictionary with the global and remove redundant data */
  146.     keyList = PLGetAllDictionaryKeys(GlobalDB);
  147. /*    puts(PLGetDescription(WindowMakerDB));*/
  148.     for (i=0; i<PLGetNumberOfElements(keyList); i++) {
  149.     key = PLGetArrayElement(keyList, i);
  150.     
  151.     /* We don't have this value anyway, so no problem. 
  152.      * Probably  a new option */
  153.     p1 = PLGetDictionaryEntry(WindowMakerDB, key);
  154.     if (!p1)
  155.         continue;
  156.     /* The global doesn't have it, so no problem either. */
  157.     p2 = PLGetDictionaryEntry(GlobalDB, key);
  158.     if (!p2)
  159.         continue;
  160.     /* If both values are the same, don't save. */
  161.     if (PLIsEqual(p1, p2))
  162.         PLRemoveDictionaryEntry(WindowMakerDB, key);
  163.     }
  164. /*    puts(PLGetDescription(WindowMakerDB));*/
  165.     PLRelease(keyList);
  166. /*    puts("storing data");*/
  167.  
  168.     PLSave(WindowMakerDB, YES);
  169.     
  170.  
  171.     memset(&ev, 0, sizeof(XEvent));
  172.         
  173.     ev.xclient.type = ClientMessage;
  174.     ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)),
  175.                       "_WINDOWMAKER_COMMAND", False);
  176.     ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
  177.     ev.xclient.format = 8;
  178.  
  179.     for (i = 0; i <= strlen(msg); i++) {
  180.     ev.xclient.data.b[i] = msg[i];
  181.     }
  182.     XSendEvent(WMScreenDisplay(WMWidgetScreen(w)), 
  183.            DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))),
  184.            False, SubstructureRedirectMask, &ev);
  185.     XFlush(WMScreenDisplay(WMWidgetScreen(w)));
  186. }
  187.  
  188.  
  189.  
  190. static void
  191. undo(WMWidget *w, void *data)
  192. {
  193.     PanelRec *rec = (PanelRec*)WPrefs.currentPanel;
  194.     
  195.     if (!rec)
  196.     return;
  197.  
  198.     if (rec->callbacks.undoChanges 
  199.     && (rec->callbacks.flags & INITIALIZED_PANEL)) {
  200.     (*rec->callbacks.undoChanges)(WPrefs.currentPanel);
  201.     }
  202. }
  203.  
  204.  
  205. static void
  206. undoAll(WMWidget *w, void *data)
  207. {
  208.     int i;
  209.     
  210.     for (i=0; i<WPrefs.sectionCount; i++) {
  211.     PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
  212.  
  213.     if (rec->callbacks.undoChanges 
  214.         && (rec->callbacks.flags & INITIALIZED_PANEL))
  215.         (*rec->callbacks.undoChanges)((Panel*)rec);
  216.     }
  217. }
  218.  
  219.  
  220.  
  221. static void
  222. prepareForClose()
  223. {
  224.     int i;
  225.  
  226.     for (i=0; i<WPrefs.sectionCount; i++) {
  227.     PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
  228.  
  229.     if (rec->callbacks.prepareForClose 
  230.         && (rec->callbacks.flags & INITIALIZED_PANEL))
  231.         (*rec->callbacks.prepareForClose)((Panel*)rec);
  232.     }
  233. }
  234.  
  235.  
  236. void
  237. toggleBalloons(WMWidget *w, void *data)
  238. {
  239.     WMUserDefaults *udb = WMGetStandardUserDefaults();
  240.     Bool flag;
  241.  
  242.     flag = WMGetButtonSelected(WPrefs.balloonBtn);
  243.  
  244.     WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
  245.  
  246.     WMSetUDBoolForKey(udb, flag, "BalloonHelp");
  247. }
  248.  
  249.  
  250. static void
  251. createMainWindow(WMScreen *scr)
  252. {
  253.     WMScroller *scroller;
  254.     WMFont *font;
  255.     char buffer[128];
  256.  
  257.     WPrefs.win = WMCreateWindow(scr, "wprefs");
  258.     WMResizeWidget(WPrefs.win, 520, 390);
  259.     WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
  260.     WMSetWindowCloseAction(WPrefs.win, quit, NULL);
  261.     WMSetWindowMaxSize(WPrefs.win, 520, 390);
  262.     WMSetWindowMinSize(WPrefs.win, 520, 390);
  263.     WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
  264.     WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
  265.     
  266.     WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
  267.     WMResizeWidget(WPrefs.scrollV, 500, 87);
  268.     WMMoveWidget(WPrefs.scrollV, 10, 10);
  269.     WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
  270.     WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
  271.     WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
  272.     scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
  273.     WMSetScrollerArrowsPosition(scroller, WSANone);
  274.  
  275.     WPrefs.buttonF = WMCreateFrame(WPrefs.win);
  276.     WMSetFrameRelief(WPrefs.buttonF, WRFlat);
  277.  
  278.     WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
  279.  
  280.     WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
  281.     WMResizeWidget(WPrefs.undosBtn, 90, 28);
  282.     WMMoveWidget(WPrefs.undosBtn, 135, 350);
  283.     WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
  284.     WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
  285.     
  286.     WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
  287.     WMResizeWidget(WPrefs.undoBtn, 90, 28);
  288.     WMMoveWidget(WPrefs.undoBtn, 235, 350);
  289.     WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
  290.     WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
  291.  
  292.     WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
  293.     WMResizeWidget(WPrefs.saveBtn, 80, 28);
  294.     WMMoveWidget(WPrefs.saveBtn, 335, 350);
  295.     WMSetButtonText(WPrefs.saveBtn, _("Save"));
  296.     WMSetButtonAction(WPrefs.saveBtn, save, NULL);
  297.     
  298.     WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
  299.     WMResizeWidget(WPrefs.closeBtn, 80, 28);
  300.     WMMoveWidget(WPrefs.closeBtn, 425, 350);
  301.     WMSetButtonText(WPrefs.closeBtn, _("Close"));
  302.     WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
  303.  
  304.  
  305.     WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
  306.     WMResizeWidget(WPrefs.balloonBtn, 200, 28);
  307.     WMMoveWidget(WPrefs.balloonBtn, 15, 350);
  308.     WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
  309.     WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
  310.     {
  311.     WMUserDefaults *udb = WMGetStandardUserDefaults();
  312.     Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
  313.  
  314.     WMSetButtonSelected(WPrefs.balloonBtn, flag);
  315.     WMSetBalloonEnabled(scr, flag);
  316.     }
  317.  
  318.     /* banner */
  319.     WPrefs.banner = WMCreateFrame(WPrefs.win);
  320.     WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
  321.     WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
  322.     WMSetFrameRelief(WPrefs.banner, WRFlat);
  323.  
  324.     font = WMCreateFont(scr, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*,"
  325.             "-*-fixed-medium-r-normal-*-24-*");
  326.     if (!font)
  327.     font = WMBoldSystemFontOfSize(scr, 24);
  328.     WPrefs.nameL = WMCreateLabel(WPrefs.banner);
  329.     WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
  330.     WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 30);
  331.     WMMoveWidget(WPrefs.nameL, 10, 25);
  332.     WMSetLabelFont(WPrefs.nameL, font);
  333.     WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences Utility"));
  334.     WMReleaseFont(font);
  335.  
  336.     WPrefs.versionL = WMCreateLabel(WPrefs.banner);
  337.     WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
  338.     WMMoveWidget(WPrefs.versionL, 10, 65);
  339.     WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
  340.     sprintf(buffer, _("Version %s for Window Maker %s or newer"), WVERSION,
  341.                                  WMVERSION);
  342.     WMSetLabelText(WPrefs.versionL, buffer);
  343.  
  344.     WPrefs.statusL = WMCreateLabel(WPrefs.banner);
  345.     WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
  346.     WMMoveWidget(WPrefs.statusL, 10, 100);
  347.     WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
  348.     WMSetLabelText(WPrefs.statusL, _("Starting..."));
  349.      
  350.     WPrefs.creditsL = WMCreateLabel(WPrefs.banner);
  351.     WMResizeWidget(WPrefs.creditsL, FRAME_WIDTH-20, 60);
  352.     WMMoveWidget(WPrefs.creditsL, 10, FRAME_HEIGHT-60);
  353.     WMSetLabelTextAlignment(WPrefs.creditsL, WACenter);
  354.     WMSetLabelText(WPrefs.creditsL, _("Programming/Design: Alfredo K. Kojima\n"
  355.                    "Artwork: Marco van Hylckama Vlieg and Largo\n"
  356.                       "More Programming: James Thompson"));
  357.    
  358.     
  359.     WMMapSubwidgets(WPrefs.win);
  360.     
  361.     WMUnmapWidget(WPrefs.undosBtn);
  362.     WMUnmapWidget(WPrefs.undoBtn);
  363.     WMUnmapWidget(WPrefs.saveBtn);
  364. }
  365.  
  366.  
  367. static void
  368. showPanel(Panel *panel)
  369. {
  370.     PanelRec *rec = (PanelRec*)panel;
  371.     
  372.     if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
  373.     (*rec->callbacks.createWidgets)(panel);
  374.     rec->callbacks.flags |= INITIALIZED_PANEL;
  375.     }
  376.  
  377.     WMSetWindowTitle(WPrefs.win, rec->sectionName);
  378.     
  379.     WMMapWidget(rec->frame);
  380. }
  381.  
  382.  
  383.  
  384. static void
  385. hidePanel(Panel *panel)
  386. {
  387.     PanelRec *rec = (PanelRec*)panel;    
  388.     
  389.     WMUnmapWidget(rec->frame);
  390. }
  391.  
  392.  
  393. static void
  394. savePanelData(Panel *panel)
  395. {
  396.     PanelRec *rec = (PanelRec*)panel;    
  397.  
  398.     if (rec->callbacks.updateDomain) {
  399.     (*rec->callbacks.updateDomain)(panel);
  400.     }
  401. }
  402.  
  403.  
  404. static void 
  405. changeSection(WMWidget *self, void *data)
  406. {
  407.     if (WPrefs.banner) {
  408.     WMDestroyWidget(WPrefs.banner);
  409.     WPrefs.banner = NULL;
  410. /*    WMMapWidget(WPrefs.undosBtn);
  411.     WMMapWidget(WPrefs.undoBtn);
  412.  */
  413.     WMMapWidget(WPrefs.saveBtn);
  414.     }
  415.     
  416.     showPanel(data);
  417.     
  418.     if (WPrefs.currentPanel)
  419.     hidePanel(WPrefs.currentPanel);
  420.     WPrefs.currentPanel = data;
  421. }
  422.  
  423.  
  424.  
  425.  
  426.  
  427. char*
  428. LocateImage(char *name)
  429. {
  430.     char *path;
  431.     char *tmp = wmalloc(strlen(name)+8);
  432.         
  433.     if (TIFFOK) {
  434.     sprintf(tmp, "%s.tiff", name);
  435.     path = WMPathForResourceOfType(tmp, "tiff");
  436.     } else {
  437.     sprintf(tmp, "%s.xpm", name);
  438.     path = WMPathForResourceOfType(tmp, "xpm");
  439.     }
  440.     free(tmp);
  441.     if (!path) {
  442.     wwarning(_("could not locate image file %s\n"), name);
  443.     }
  444.     
  445.     return path;
  446. }
  447.  
  448.  
  449.  
  450. static WMPixmap*
  451. makeTitledIcon(WMScreen *scr, WMPixmap *icon, char *title1, char *title2)
  452. {
  453.     return WMRetainPixmap(icon);
  454.     
  455. #if 0
  456.     static GC gc = NULL;
  457.     static XFontStruct *hfont = NULL;
  458.     static XFontStruct *vfont = NULL;
  459.     WMPixmap *tmp;
  460.     Pixmap pix, mask;
  461.     Display *dpy = WMScreenDisplay(scr);
  462.     WMColor *black = WMBlackColor(scr);
  463.     GC fgc;
  464.     WMSize size = WMGetPixmapSize(icon);
  465.  
  466.     
  467.     tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
  468.  
  469.     pix = WMGetPixmapXID(tmp);
  470.     mask = WMGetPixmapMaskXID(tmp);
  471.  
  472.     if (gc == NULL) {
  473.     gc = XCreateGC(dpy, mask, 0, NULL);
  474.  
  475.     hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
  476.     vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
  477.     }
  478.     
  479.     if (hfont == NULL) {
  480.     return WMRetainPixmap(icon);
  481.     }
  482.     
  483.     XSetForeground(dpy, gc, 0);
  484.     XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
  485.     
  486.     fgc = WMColorGC(black);
  487.     
  488.     XSetForeground(dpy, gc, 1);
  489.     
  490.     XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0,
  491.           size.width, size.height, 12, 12);
  492.     
  493.     if (WMGetPixmapMaskXID(icon) != None)
  494.     XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0,
  495.            size.width, size.height, 12, 12, 1);
  496.     else
  497.     XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
  498.  
  499.  
  500.     if (title1) {
  501.     XSetFont(dpy, fgc, vfont->fid);
  502.     XSetFont(dpy, gc, vfont->fid);
  503.  
  504.     XDrawString(dpy, pix, fgc, 0, vfont->ascent, 
  505.             title1, strlen(title1));
  506.     
  507.     XDrawString(dpy, mask, gc, 0, vfont->ascent, 
  508.             title1, strlen(title1));
  509.     }
  510.  
  511.     if (title2) {
  512.     XSetFont(dpy, fgc, hfont->fid);
  513.     XSetFont(dpy, gc, hfont->fid);
  514.  
  515.     XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent, 
  516.             title2, strlen(title2));
  517.     
  518.     XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent, 
  519.             title2, strlen(title2));
  520.     }
  521.  
  522.     return tmp;
  523. #endif
  524. }
  525.  
  526.  
  527. void
  528. SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, char *file,
  529.             char *title1, char *title2)
  530. {
  531.     WMPixmap *icon;
  532.     WMPixmap *icon2;
  533.     RColor color;
  534.     char *iconPath;
  535.  
  536.     iconPath = LocateImage(file);
  537.  
  538.     color.red = 0xae;
  539.     color.green = 0xaa;
  540.     color.blue = 0xae;
  541.     color.alpha = 0;
  542.     if (iconPath) {
  543.     icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
  544.     if (!icon)
  545.         wwarning(_("could not load icon file %s"), iconPath);
  546.     } else {
  547.     icon = NULL;
  548.     }
  549.     
  550.     if (icon) {
  551.     icon2 = makeTitledIcon(scr, icon, title1, title2);
  552.     if (icon)
  553.         WMReleasePixmap(icon);
  554.     } else {
  555.     icon2 = NULL;
  556.     }
  557.     
  558.     WMSetButtonImage(bPtr, icon2);
  559.  
  560.     if (icon2)
  561.     WMReleasePixmap(icon2);
  562.  
  563.     color.red = 0xff;
  564.     color.green = 0xff;
  565.     color.blue = 0xff;
  566.     color.alpha = 0;
  567.     if (iconPath) {
  568.     icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
  569.     if (!icon)
  570.         wwarning(_("could not load icon file %s"), iconPath);
  571.     } else {
  572.     icon = NULL;
  573.     }
  574.  
  575.     WMSetButtonAltImage(bPtr, icon);
  576.  
  577.     if (icon)
  578.     WMReleasePixmap(icon);
  579.  
  580.     if (iconPath)
  581.     free(iconPath);
  582. }
  583.  
  584.  
  585. void
  586. AddSection(Panel *panel, char *iconFile)
  587. {
  588.     WMButton *bPtr;
  589.  
  590.     assert(WPrefs.sectionCount < MAX_SECTIONS);
  591.     
  592.  
  593.     bPtr = WMCreateCustomButton(WPrefs.buttonF,    WBBStateLightMask
  594.                 |WBBStateChangeMask);
  595.     WMResizeWidget(bPtr, 64, 64);
  596.     WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
  597.     WMSetButtonImagePosition(bPtr, WIPImageOnly);
  598.     WMSetButtonAction(bPtr, changeSection, panel);
  599.     WMHangData(bPtr, panel);
  600.  
  601.     WMSetBalloonTextForView(((PanelRec*)panel)->description,
  602.                 WMWidgetView(bPtr));
  603.  
  604.     {
  605.     char *t1, *t2;
  606.     
  607.     t1 = wstrdup(((PanelRec*)panel)->sectionName);
  608.     t2 = strchr(t1, ' ');
  609.     if (t2) {
  610.         *t2 = 0;
  611.         t2++;
  612.     }
  613.     SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile,
  614.                 t1, t2);
  615.     free(t1);
  616.     }
  617.     WMMapWidget(bPtr);
  618.  
  619.     WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
  620.  
  621.     if (WPrefs.sectionCount > 0) {
  622.     WMGroupButtons(WPrefs.sectionB[0], bPtr);
  623.     }
  624.  
  625.     WPrefs.sectionCount++;
  626.  
  627.     WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
  628. }
  629.  
  630.  
  631. void
  632. Initialize(WMScreen *scr)
  633. {
  634.     char **list;
  635.     int i;
  636.     char *path;
  637.     WMPixmap *icon;
  638.     
  639.     
  640.     list = RSupportedFileFormats();
  641.     for (i=0; list[i]!=NULL; i++) {
  642.     if (strcmp(list[i], "TIFF")==0) {
  643.         TIFFOK = True;
  644.         break;
  645.     }
  646.     }
  647.     
  648.     if (TIFFOK)
  649.         path = WMPathForResourceOfType("WPrefs.tiff", NULL);
  650.     else
  651.     path = WMPathForResourceOfType("WPrefs.xpm", NULL);
  652.     if (path) {
  653.     RImage *tmp;
  654.     
  655.     tmp = RLoadImage(WMScreenRContext(scr), path, 0);
  656.     if (!tmp) {
  657.         wwarning(_("could not load image file %s:%s"), path,
  658.              RMessageForError(RErrorCode));
  659.     } else {
  660.         icon = WMCreatePixmapFromRImage(scr, tmp, 0);
  661.         RDestroyImage(tmp);
  662.         if (icon) {
  663.             WMSetApplicationIconImage(scr, icon);
  664.             WMReleasePixmap(icon);
  665.         }
  666.     }
  667.     free(path);
  668.     }
  669.     
  670.     memset(&WPrefs, 0, sizeof(_WPrefs));
  671.     createMainWindow(scr);
  672.  
  673.     WMRealizeWidget(WPrefs.win);
  674.     WMMapWidget(WPrefs.win);
  675.     XFlush(WMScreenDisplay(scr));
  676.     WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
  677.     XFlush(WMScreenDisplay(scr));
  678.     loadConfigurations(scr, WPrefs.win);
  679.  
  680.     WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
  681.  
  682.     InitWindowHandling(scr, WPrefs.win);
  683.     InitFocus(scr, WPrefs.win);
  684.     InitMenuPreferences(scr, WPrefs.win);
  685.     InitIcons(scr, WPrefs.win);
  686.     InitPreferences(scr, WPrefs.win);
  687.  
  688.     InitPaths(scr, WPrefs.win);    
  689.     InitWorkspace(scr, WPrefs.win);
  690.     InitConfigurations(scr, WPrefs.win);
  691.  
  692.     InitMenu(scr, WPrefs.win);
  693.  
  694. #ifdef not_yet_fully_implemented
  695.     InitKeyboardSettings(scr, WPrefs.win);
  696. #endif
  697.     InitKeyboardShortcuts(scr, WPrefs.win);
  698.     InitMouseSettings(scr, WPrefs.win);
  699.  
  700.     InitAppearance(scr, WPrefs.win);
  701.     
  702. #ifdef akk
  703.     InitFont(scr, WPrefs.win);
  704. #endif
  705. #ifdef not_yet_fully_implemented
  706.     InitThemes(scr, WPrefs.win);
  707. #endif
  708.     InitExpert(scr, WPrefs.win);
  709.  
  710.     WMRealizeWidget(WPrefs.scrollV);
  711.  
  712.     WMSetLabelText(WPrefs.statusL, 
  713.            _("WPrefs is free software and is distributed WITHOUT ANY\n"
  714.        "WARRANTY under the terms of the GNU General Public License."));
  715. }
  716.  
  717.  
  718. WMWindow*
  719. GetWindow(Panel *panel)
  720. {
  721.     return WPrefs.win;
  722. }
  723.  
  724.  
  725. static void
  726. loadConfigurations(WMScreen *scr, WMWindow *mainw)
  727. {
  728.     proplist_t db, gdb;
  729.     char *path;
  730.     FILE *file;
  731.     char buffer[1024];
  732.     char mbuf[1024];
  733.     int v1, v2, v3;
  734.     
  735.     path = wdefaultspathfordomain("WindowMaker");
  736.     
  737.     db = PLGetProplistWithPath(path);
  738.     if (db) {
  739.     if (!PLIsDictionary(db)) {
  740.         PLRelease(db);
  741.         db = NULL;
  742.         sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
  743.         WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
  744.     }
  745.     } else {
  746.     sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."),
  747.         path);
  748.     WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
  749.     }
  750.     free(path);
  751.  
  752.     path = getenv("WMAKER_BIN_NAME");
  753.     if (!path)
  754.     path = "wmaker";
  755.     path = wstrappend(path, " --version");
  756.  
  757.     file = popen(path, "r");
  758.     if (!file || !fgets(buffer, 1023, file)) {
  759.     wsyserror(_("could not extract version information from Window Maker"));
  760.     wfatal(_("Make sure wmaker is in your search path."));
  761.     
  762.     WMRunAlertPanel(scr, mainw, _("Error"),
  763.             _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
  764.             _("OK"), NULL, NULL);
  765.     exit(1);
  766.     }
  767.     if (file)
  768.     pclose(file);
  769.     
  770.     if (sscanf(buffer, "Window Maker %i.%i.%i",&v1,&v2,&v3)!=3
  771.     && sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
  772.     WMRunAlertPanel(scr, mainw, _("Error"),
  773.             _("Could not extract version from Window Maker. "
  774.               "Make sure it is correctly installed and the path "
  775.               "where it installed is in the PATH environment "
  776.               "variable."), _("OK"), NULL, NULL);
  777.     exit(1);
  778.     }
  779.     if (v1 == 0 && (v2 < 18 || v3 < 0)) {
  780.     sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
  781.         "The version installed is %i.%i.%i\n"), v1, v2, v3);
  782.     WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
  783.     exit(1);
  784.  
  785.     }
  786.     if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
  787.     sprintf(mbuf, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
  788.         v1, v2, v3);
  789.     WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
  790.     }
  791.  
  792.     file = popen("wmaker --global_defaults_path", "r");
  793.     if (!file || !fgets(buffer, 1023, file)) {
  794.     wsyserror(_("could not run \"wmaker --global_defaults_path\"."));
  795.     exit(1);
  796.     } else {
  797.     char *ptr;
  798.     ptr = strchr(buffer, '\n');
  799.     if (ptr)
  800.         *ptr = 0;
  801.     strcat(buffer, "/WindowMaker");
  802.     }
  803.  
  804.     if (file)
  805.     pclose(file);
  806.  
  807.     gdb = PLGetProplistWithPath(buffer);
  808.     if (gdb) {
  809.     if (!PLIsDictionary(gdb)) {
  810.         PLRelease(gdb);
  811.         gdb = NULL;
  812.         sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
  813.         WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
  814.     }
  815.     } else {
  816.     sprintf(mbuf, _("Could not load global Window Maker domain (%s)."),
  817.         buffer);
  818.     WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
  819.     }
  820.  
  821.     if (!db) {
  822.     db = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
  823.     }
  824.     if (!gdb) {
  825.     gdb = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
  826.     }
  827.  
  828.     GlobalDB = gdb;
  829.  
  830.     WindowMakerDB = db;
  831. }
  832.  
  833.  
  834. proplist_t
  835. GetObjectForKey(char *defaultName)
  836. {
  837.     proplist_t object = NULL;
  838.     proplist_t key = PLMakeString(defaultName);
  839.  
  840.     object = PLGetDictionaryEntry(WindowMakerDB, key);
  841.     if (!object)
  842.     object = PLGetDictionaryEntry(GlobalDB, key);
  843.  
  844.     PLRelease(key);
  845.  
  846.     return object;
  847. }
  848.  
  849.  
  850. void
  851. SetObjectForKey(proplist_t object, char *defaultName)
  852. {
  853.     proplist_t key = PLMakeString(defaultName);
  854.  
  855.     PLInsertDictionaryEntry(WindowMakerDB, key, object);
  856.     PLRelease(key);
  857. }
  858.  
  859.  
  860. void
  861. RemoveObjectForKey(char *defaultName)
  862. {
  863.     proplist_t key = PLMakeString(defaultName);
  864.     
  865.     PLRemoveDictionaryEntry(WindowMakerDB, key);
  866.     
  867.     PLRelease(key);
  868. }
  869.  
  870.  
  871. char*
  872. GetStringForKey(char *defaultName)
  873. {
  874.     proplist_t val;
  875.     
  876.     val = GetObjectForKey(defaultName);
  877.  
  878.     if (!val)
  879.     return NULL;
  880.  
  881.     if (!PLIsString(val))
  882.     return NULL;
  883.  
  884.     return PLGetString(val);
  885. }
  886.  
  887.  
  888.  
  889. proplist_t
  890. GetArrayForKey(char *defaultName)
  891. {
  892.     proplist_t val;
  893.     
  894.     val = GetObjectForKey(defaultName);
  895.     
  896.     if (!val)
  897.     return NULL;
  898.  
  899.     if (!PLIsArray(val))
  900.     return NULL;
  901.  
  902.     return val;
  903. }
  904.  
  905.  
  906. proplist_t
  907. GetDictionaryForKey(char *defaultName)
  908. {
  909.     proplist_t val;
  910.  
  911.     val = GetObjectForKey(defaultName);
  912.     
  913.     if (!val)
  914.     return NULL;
  915.  
  916.     if (!PLIsDictionary(val))
  917.     return NULL;
  918.  
  919.     return val;
  920. }
  921.  
  922.  
  923. int
  924. GetIntegerForKey(char *defaultName)
  925. {
  926.     proplist_t val;
  927.     char *str;
  928.     int value;
  929.  
  930.     val = GetObjectForKey(defaultName);
  931.     
  932.     if (!val)
  933.     return 0;
  934.  
  935.     if (!PLIsString(val))
  936.     return 0;
  937.     
  938.     str = PLGetString(val);
  939.     if (!str)
  940.     return 0;
  941.     
  942.     if (sscanf(str, "%i", &value)!=1)
  943.     return 0;
  944.  
  945.     return value;
  946. }
  947.  
  948.  
  949. Bool
  950. GetBoolForKey(char *defaultName)
  951. {
  952.     int value;
  953.     char *str;
  954.  
  955.     str = GetStringForKey(defaultName);
  956.     
  957.     if (!str)
  958.     return False;
  959.     
  960.     if (sscanf(str, "%i", &value)==1 && value!=0)
  961.     return True;
  962.  
  963.     if (strcasecmp(str, "YES")==0)
  964.     return True;
  965.     
  966.     if (strcasecmp(str, "Y")==0)
  967.     return True;
  968.  
  969.     return False;
  970. }
  971.  
  972.  
  973. void
  974. SetIntegerForKey(int value, char *defaultName)
  975. {
  976.     proplist_t object;
  977.     char buffer[128];
  978.  
  979.     sprintf(buffer, "%i", value);
  980.     object = PLMakeString(buffer);
  981.  
  982.     SetObjectForKey(object, defaultName);
  983.     PLRelease(object);
  984. }
  985.  
  986.  
  987.  
  988. void
  989. SetStringForKey(char *value, char *defaultName)
  990. {
  991.     proplist_t object;
  992.  
  993.     object = PLMakeString(value);
  994.  
  995.     SetObjectForKey(object, defaultName);
  996.     PLRelease(object);
  997. }
  998.  
  999.  
  1000. void
  1001. SetBoolForKey(Bool value, char *defaultName)
  1002. {
  1003.     static proplist_t yes = NULL, no = NULL;
  1004.  
  1005.     if (!yes) {
  1006.     yes = PLMakeString("YES");
  1007.     no = PLMakeString("NO");
  1008.     }
  1009.  
  1010.     SetObjectForKey(value ? yes : no, defaultName);
  1011. }
  1012.  
  1013.  
  1014. void
  1015. SetSpeedForKey(int speed, char *defaultName)
  1016. {
  1017.     char *str;
  1018.     
  1019.     switch (speed) {
  1020.      case 0:
  1021.     str = "ultraslow";
  1022.     break;
  1023.      case 1:
  1024.     str = "slow";
  1025.     break;
  1026.      case 2:
  1027.     str = "medium";
  1028.     break;
  1029.      case 3:
  1030.     str = "fast";
  1031.     break;
  1032.      case 4:
  1033.     str = "ultrafast";
  1034.     break;
  1035.      default:
  1036.     str = NULL;
  1037.     }
  1038.     
  1039.     if (str)
  1040.     SetStringForKey(str, defaultName);
  1041. }
  1042.  
  1043.  
  1044. int
  1045. GetSpeedForKey(char *defaultName)
  1046. {
  1047.     char *str;
  1048.     int i;
  1049.     
  1050.     str = GetStringForKey(defaultName);
  1051.     if (!str)
  1052.     return 2;
  1053.  
  1054.     if (strcasecmp(str, "ultraslow")==0)
  1055.     i = 0;
  1056.     else if (strcasecmp(str, "slow")==0)
  1057.     i = 1;
  1058.     else if (strcasecmp(str, "medium")==0)
  1059.     i = 2;
  1060.     else if (strcasecmp(str, "fast")==0)
  1061.     i = 3;
  1062.     else if (strcasecmp(str, "ultrafast")==0)
  1063.     i = 4;
  1064.     else {
  1065.     wwarning(_("bad speed value for option %s\n. Using default Medium"),
  1066.          defaultName);
  1067.     i = 2;
  1068.     }
  1069.     return i;
  1070. }
  1071.  
  1072.  
  1073.